/**
 * 
 */
package org.bookie.core.services.impl;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.apache.commons.logging.Log;
import org.apache.hivemind.lib.NameLookup;
import org.bookie.core.services.IMailSender;
import org.bookie.core.services.ITransport;

/**
 * Sends mails
 * 
 * @author zubairov
 * 
 */
public class MailSenderImpl implements IMailSender {

	private static final String HTML_MIME_TYPE = "text/html;charset=\"UTF-8\"";

	private static final String PLAIN_MIME_TYPE = "text/plain";

	private Log log;

	private NameLookup nameLookup;

	private String jndiName;

	private ITransport transport;

	/**
	 * Send an email to the address with content
	 * 
	 * @throws MessagingException
	 * 
	 * @see org.bookie.core.services.IMailSender#sendEmail(java.lang.String,
	 *      java.lang.String)
	 */
	public void sendEmail(String to, String subject, String message)
			throws MessagingException {
		sendMessage(to, subject, message, PLAIN_MIME_TYPE);
	}

	/**
	 * {@inheritDoc}
	 */
	public void sendHTMLEmail(String to, String subject, String htmlMessage)
			throws MessagingException {
		sendMessage(to, subject, htmlMessage, HTML_MIME_TYPE);
	}

	/**
	 * Sending message
	 * 
	 * @param to
	 * @param subject
	 * @param message
	 * @param contentType
	 * @throws MessagingException
	 */
	private void sendMessage(final String to, String subject, String message,
			String contentType) throws MessagingException {
		Session session = (Session) nameLookup.lookup(jndiName, Session.class);
		if (session == null) {
			log.error("Can't find mail session under JNDI name " + jndiName);
			return;
		}
		log.debug("Mail session found under " + jndiName);
		final Message msg = new MimeMessage(session);
		msg.setSubject(subject);
		msg.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(to));
		msg.setContent(message, contentType);
		if (log.isDebugEnabled()) {
			log.debug("Sending message to :" + to + "\n" + "with subject:"
					+ subject + "\n" + "Content: " + message);
		}
		Thread messageSendingThread = new Thread() {
			public void run() {
				try {
					getTransport().send(msg);
					log.info("Message with subject " + msg.getSubject()
							+ " to " + to + " was sent");
				} catch (MessagingException me) {
					log.warn("Error while sending email:", me);
				}
			}
		};
		messageSendingThread.start();
	}

	/**
	 * Injected logger
	 * 
	 * @param log
	 */
	public void setLog(Log log) {
		this.log = log;
	}

	/**
	 * Injected hivemind lib service
	 * 
	 * @param nameLookup
	 */
	public void setNameLookup(NameLookup nameLookup) {
		this.nameLookup = nameLookup;
	}

	/**
	 * JNDI name for the mail session
	 * 
	 * @param jndiName
	 */
	public void setJndiName(String jndiName) {
		this.jndiName = jndiName;
	}

	public void setTransport(ITransport transport) {
		this.transport = transport;
	}

	/**
	 * Injected transport
	 * 
	 * @return
	 */
	public ITransport getTransport() {
		return transport;
	}
}
